package com.tea.modules.java8.stream;

import com.google.common.collect.Lists;
import com.tea.modules.model.po.Student;
import com.tea.modules.model.po.StudentForLambda;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.Map;
import java.util.stream.Collectors;

public class Reduce {
    public static void main(String[] args) {
//        Product productA = new Product("iPhone11", BigDecimal.valueOf(5499),BigDecimal.valueOf(1.7),1);
//        Product productB = new Product("HUAWEI P40", BigDecimal.valueOf(4188),BigDecimal.valueOf(2),2);
//        Product productC = new Product("OPPO Find X", BigDecimal.valueOf(6999),BigDecimal.valueOf(1.1),5);
//        Product productD = new Product("SAMSUNG", BigDecimal.valueOf(8888),BigDecimal.valueOf(2.5),3);
//        List<Product> products = Arrays.asList(productA, productB, productC, productD);
//        System.out.println(products.stream().map(Product::getNum).reduce((a, b) -> a + b).get());
//        System.out.println(products.stream().map(Product::getPrice).reduce((a, b) -> a.add(b)).get());
//        System.out.println(products.stream().map(Product::getWeight).reduce((a, b) -> a.add(b)).get());

        StudentForLambda studentA = new StudentForLambda(1L, "特朗普", 45, "漂亮国");
        StudentForLambda studentB = new StudentForLambda(2L, "大雄", 30, "日本");
        StudentForLambda studentC = new StudentForLambda(3L, "拿破仑", 60, "法国");
        StudentForLambda studentD = new StudentForLambda(4L, "孙中山", 25, "中国");
        StudentForLambda studentE = new StudentForLambda(5L, "毛", 31, "中国");
        List<StudentForLambda> chineseMen = Lists.newArrayList(studentD, studentE);
        List<StudentForLambda> usaMen = Lists.newArrayList(studentA);
        Map<String, List<StudentForLambda>> world = new HashMap<>();
        world.put("中国", chineseMen);
        world.put("美国", usaMen);
        if (CollectionUtils.isEmpty(world)) {
            return;
        }
        Integer sum = 0;
        for (Map.Entry<String, List<StudentForLambda>> w : world.entrySet()) {
            String key = w.getKey();
            List<StudentForLambda> persons = w.getValue();
            if (!Objects.equals("中国", key) && !Objects.equals("美国", key)) {
                continue;
            }
            if (CollectionUtils.isEmpty(persons)) {
                return;
            }
            for (StudentForLambda person : persons) {
                int age = person.getAge();
                sum += age;
            }
        }
        System.out.println(sum);
        int countrySum = world.entrySet().stream()
                .filter(c -> Objects.equals("中国", c.getKey()) || Objects.equals("美国", c.getKey()))
                .mapToInt(country -> {
                    List<StudentForLambda> persons = country.getValue();
                    return persons.stream().mapToInt(StudentForLambda::getAge).sum();
                }).sum();
        System.out.println(countrySum);
        List<StudentForLambda> studentList = Arrays.asList(studentA, studentB, studentC, studentD);
        String s = studentList.stream().reduce(
                new StringBuffer(), (result, value) -> {
                    System.out.println(result + "我是result");
                    System.out.println(value.toString());
                    return result.append(value.getId()).append(",").append(value.getName()).append(",");
                },
                (result, value) -> result
        ).toString();
        s = s.substring(0, s.length() - 1);
        System.out.println(s);
//        String s1 = studentList.stream().reduce(new StringBuffer(), (result, student) ->
//                        result.append(student.getId()).append(",").append(student.getName()).append(","),
//                        (result, student) -> result).toString();
//        System.out.println(s1);
//        int sum = studentList.stream().mapToInt(StudentForLambda::getAge).sum();
        System.out.println("年龄总和:" + sum);

        // 很有意思的一个写法
        selectNamesGroupByCountry();
    }

    /**
     * 这里我们要实现一个这样的逻辑
     * 查询相同国家的人名集合
     */
    public static void selectNamesGroupByCountry() {
        StudentForLambda studentA = new StudentForLambda(1L, "特朗普", 45, "漂亮国");
        StudentForLambda studentB = new StudentForLambda(2L, "大雄", 30, "日本");
        StudentForLambda studentC = new StudentForLambda(3L, "拿破仑", 60, "法国");
        StudentForLambda studentD = new StudentForLambda(4L, "孙中山", 25, "中国");
        StudentForLambda studentE = new StudentForLambda(5L, "毛", 31, "中国");
        List<StudentForLambda> students = Lists.newArrayList(studentA, studentB, studentC, studentD, studentE);
        Map<String, String> result = students.stream().collect(Collectors.groupingBy(
                StudentForLambda::getAddress,
                Collectors.reducing("名字集合", StudentForLambda::getName, (r, s) -> r + "," + s)
        ));
        // 一个疑问，这里的new貌似无效
        Map<String, List<Integer>> resultA = students.stream().collect(Collectors.groupingBy(
                StudentForLambda::getAddress,
                Collectors.reducing(new ArrayList<>(), s -> {
                    List<Integer> rr = new ArrayList<>();
                    rr.add(s.getAge());
                    return rr;
                }, (r, ss) -> {
                    r.addAll(ss);
                    return r;
                })
        ));
        result.forEach((k, v) -> System.out.println(k + "---" + v));

        resultA.forEach((k, v) -> System.out.println(k + "---" + v));
    }
}
